package com.game.model;

import com.game.interfaces.Draw;
import com.game.main.GameContext;
import com.game.util.ImageUtil;
import com.game.util.PropertiesUtil;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: tjc
 * @description
 * @Date Created in 21:18 2021-08-11
 */
public class StageSelector implements Draw, KeyListener {
    private List<Stage> stageList;
    private int selectedIndex;

    public StageSelector(String configLocation) {
        List<Stage> stages = loadStageConfig(configLocation);
        if (stages == null && stages.size() == 0) {
            throw new RuntimeException("stages is empty!");
        }
        stageList = stages;
        selectedIndex = 0;
    }

    private List<Stage> loadStageConfig(String conf) {
        List<ConfigSection> configList = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream(conf)));) {
            String line = null;
            ConfigSection curSection = null;
            while ((line = reader.readLine()) != null) {
                String[] lineArr = line.split(" ");
                String cmd = lineArr[0];
                switch (cmd) {
                    case "start":
                        curSection = new ConfigSection();
                        int level = Integer.parseInt(lineArr[1]);
                        curSection.head = level;
                        continue;
                    case "set":
                        curSection.kvs.put(lineArr[1], lineArr[2]);
                        continue;
                    case "end":
                        configList.add(curSection);
                        curSection = null;
                        continue;
                }
            }


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return convert2Stages(configList);
    }

    private List<Stage> convert2Stages(List<ConfigSection> sections) {
        return sections.stream().map(s -> {
            Stage stage = new Stage();
            stage.setLevel(s.getHead());
            stage.setEnemyMaxNum(s.getInt("enemyMaxNum"));
            stage.setMapPath(s.getString("map"));
            stage.setEnemies(s.getIntArr("enemies"));
            return stage;
        }).sorted(Comparator.comparing(Stage::getLevel)).collect(Collectors.toList());
    }

    @Override
    public void draw(Graphics g) {
        // todo
        int a = stageList.get(selectedIndex).getLevel();
        Number n = new Number(a);
        int x = 200;
        int y = 200;
        g.drawImage(ImageUtil.stageImage, x, y, PropertiesUtil.loadInt("stage.width"), PropertiesUtil.loadInt("stage.length"), null);
        g.drawImage(ImageUtil.numberImages[a], x + PropertiesUtil.loadInt("stage.width"), y, PropertiesUtil.loadInt("number.width"), PropertiesUtil.loadInt("number.length"), null);
        n.setLocalX(x + PropertiesUtil.loadInt("stage.width"));
        n.setLocalY(y);
        n.setSIZE_X(PropertiesUtil.loadInt("number.width"));
        n.setSIZE_Y(PropertiesUtil.loadInt("number.length"));
        n.draw(g);
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        GameContext context = GameContext.getContext();
        if (e.getKeyCode() == KeyEvent.VK_W) {
            if (++selectedIndex == stageList.size()) {
                selectedIndex = 0;
            }
        } else if (e.getKeyCode() == KeyEvent.VK_S) {
            if (--selectedIndex < 0) {
                selectedIndex = stageList.size() - 1;
            }
        } else if (e.getKeyCode() == KeyEvent.VK_J) {
            context.removeKeyListener(this);
            context.startGame(stageList.get(selectedIndex));
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    private static class ConfigSection {
        int head;
        java.util.Map<String, String> kvs = new HashMap<>();

        public int getHead() {
            return head;
        }

        public void setHead(int head) {
            this.head = head;
        }

        public int getInt(String key) {
            String value = kvs.get(key);
            if (value == null)
                throw new RuntimeException();
            return Integer.parseInt(value);
        }

        public int[] getIntArr(String key) {
            String value = kvs.get(key);
            if (value == null)
                throw new RuntimeException();
            String[] arr = value.split(",");
            int[] res = new int[arr.length];
            for (int i = 0; i < arr.length; i++) {
                res[i] = Integer.parseInt(arr[i]);
            }
            return res;
        }

        public String getString(String key) {
            String value = kvs.get(key);
            if (value == null)
                throw new RuntimeException();
            return value;
        }
    }
}
